package com.bkbw.live.battle.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.BitSet;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.badlogic.gdx.math.Bezier;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.bkbw.live.battle.business.HateList.HateNode;
import com.bkbw.live.battle.business.UnitNature;
import com.bkbw.live.battle.business.behaviors.BezierMove;
import com.bkbw.live.battle.business.behaviors.BezierMove3;
import com.bkbw.live.battle.business.items.UnitEquipmentBase;
import com.bkbw.live.battle.business.items.UnitWeapon;
import com.bkbw.live.battle.database.bean.DBagItemBean;
import com.bkbw.live.common.GameConfig;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.DbBagItem;
import com.bkbw.live.common.dataproto.ClientToBattleServerPb;
import com.bkbw.live.common.dataproto.ClientToBattleServerPb.BuildListNotify;
import com.bkbw.live.common.math.MathUtils;
import com.bkbw.live.common.util.Utils;
import com.bkbw.live.common.util.Utils.FieldOperation;


public class Main {
	static {
		System.out.println("static init");
	}

	public interface testinterface {
		public void doit();
	}
	
	public static class testbaseclass {
		
	}
	
	public static class testclass extends testbaseclass implements testinterface {
		public void doit() {
			System.out.println("doit");
		}
	}
	
	public static class base {
		protected int a;
		protected int b;
		public int getA() {
			return a;
		}
		public void setA(int a) {
			this.a = a;
		}
		public int getB() {
			return b;
		}
		public void setB(int b) {
			this.b = b;
		}
		
		protected String hello;
		public String getHello() {
			return hello;
		}
		public void setHello(String hello) {
			this.hello = hello;
		}
		
	}
	
	public static class derive extends base {
		protected int c;
		protected int d;
		public int getC() {
			return c;
		}
		public void setC(int c) {
			this.c = c;
		}
		public int getD() {
			return d;
		}
		public void setD(int d) {
			this.d = d;
		}
		
		protected float f;
		public float getF() {
			return f;
		}
		public void setF(float f) {
			this.f = f;
		}
		
	}
	
	public static class pojop {
		protected int a;
		protected int b;
		public int getA() {
			return a;
		}
		public void setA(int a) {
			this.a = a;
		}
		public int getB() {
			return b;
		}
		public void setB(int b) {
			this.b = b;
		}
		protected int c;
		protected int d;
		public int getC() {
			return c;
		}
		public void setC(int c) {
			this.c = c;
		}
		public int getD() {
			return d;
		}
		public void setD(int d) {
			this.d = d;
		}
		
		protected String hello;
		public String getHello() {
			return hello;
		}
		public void setHello(String hello) {
			this.hello = hello;
		}
		
		protected Float f;
		public Float getF() {
			return f;
		}
		public void setF(Float f) {
			this.f = f;
		}
		
	}
//	public static class BezierMove3 {
//		
//		public static int Angle30 = 30;
//		public static int Angle60 = 60;
//		
//		
//		private Vector3 start = new  Vector3();
//		private Vector3 end = new  Vector3();
//		private int angle;
//		private float radians;
//		private Bezier<Vector3> bezier;
//		private Vector3 controlVector = new  Vector3();
//		private float speedLen;
//		private float bezierLen;
//		private float currentLen;
//		
//		public BezierMove3(Vector3 start, Vector3 end, int angle, float speedLen) {
//			reset(start, end, angle, speedLen);
//		}
//		
//		public void reset(Vector3 start, Vector3 end, int angle, float speedLen) {
//			this.start.set(start);
//			this.end.set(end);
//			Vector3 sub = new Vector3();
//			this.angle = angle;
//			radians = angle * GameConfig.Degree1;
//			System.out.println("radians " + radians);
//			this.speedLen = speedLen;
//			float controlVectorLen = sub.set(this.end).sub(this.start).len() / 2 / (float)Math.cos(radians);
//			
//			Vector3 yAxis = new Vector3(0, 1, 0);
//			// 3d贝塞尔和2d贝塞尔计算方式几乎一样，只是旋转是沿着一条垂直的轴来旋转，需要先求出这条轴的向量
//			Vector3 rotAxis = new Vector3();
//			Vector3 path = new Vector3();
//			path.set(this.end).sub(this.start);
//			System.out.println("path "+path);
//			rotAxis.set(this.end).sub(this.start).rotate(yAxis, -90);
//			System.out.println("rotAxis "+rotAxis);
//			controlVector.set(this.end).sub(this.start).rotate(rotAxis, angle).nor().scl(controlVectorLen).add(this.start);
//			
//			System.out.println("controlVector " + controlVector);
//			
//			Vector3[] va = new Vector3[3];
//			va[0] = new Vector3(this.start);
//			va[1] = new Vector3(this.controlVector);
//			va[2] = new Vector3(this.end);
//			bezier = new Bezier<Vector3>(va);
//			bezierLen = bezier.approxLength(5);
//		}
//		
//		public void getFirst(Vector3 pos, Vector3 derivate) {
//			bezier.valueAt(pos, 0.0f);
//			bezier.derivativeAt(derivate, 0.0f);
//		}
//		
//		public boolean move(float dt, Vector3 pos, Vector3 derivate) {
//			boolean moveEnd = false;
//			float movement = dt * speedLen;
//			currentLen += movement;
//			if (currentLen >= bezierLen) {
//				currentLen = bezierLen;
//				moveEnd = true;
//			}
//			float t = currentLen / bezierLen;
//			bezier.valueAt(pos, t);
//			bezier.derivativeAt(derivate, t);
//			return moveEnd;
//		}
//		
//		public void changeSpeed(int speedLen) {
//			this.speedLen = speedLen;
//		}
//		
//		public float getRate() {
//			return Math.abs( currentLen / bezierLen - 0.5f );
//		}
//	}
	
	static Logger logger = LoggerFactory.getLogger(GameConfig.LoggerName);
	public static void main(String[] args) throws IOException,Exception {
		testbaseclass t = new testclass();
		if (t instanceof testinterface) {
			((testinterface)t).doit();
		}
		float f = 2.5f;
		int i = Math.round(f);
		System.out.println(System.getProperty("user.dir"));
		File ff = new File("");
		System.out.println(ff.getAbsolutePath());
		System.out.println("i " + i);
		System.out.println(""+BuildListNotify.class.getName());
		System.out.println(""+BuildListNotify.class.getTypeName());
		System.out.println(""+ClientToBattleServerPb.BuildListNotify.class.getSimpleName());
		logger.info("info");
		logger.debug("debug");
		logger.warn("warn");
		logger.error("error");
		logger.trace("trace");
		
		LinkedList<Integer> li = new LinkedList<Integer>();
		li.add(9);
		li.add(5);
		li.add(3);
		li.add(8);
		li.add(2);
		System.out.println(li);
		li.sort((Integer o1, Integer o2) -> {
			if (o1 > o2)
				return 1;
			else if (o1 == o2)
				return 0;
			else 
				return -1;
		});
		System.out.println(li);
		
		/*
		int width = 1;
		int height = 2;
		int[] array = new int[width * height * 2];
		for (int z = 0; z < height; ++z){
			for (int x = 0; x < width; ++x) {
				array[(z * width + x) * 2] = x;
				array[(z * width + x) * 2 + 1] = z;
			}
		}
		System.out.println("building data start ");
		for (i = 0; i < array.length; i++) {
			System.out.print(" " + array[i]);
		}
		System.out.println("\nbuilding data end ");*/
		
		/*
		 // 测试贝塞尔曲线
		{
			Vector2[] va = new Vector2[4];
			va[0] = new Vector2(0, 0);
			va[1] = new Vector2(0, 2);
			va[2] = new Vector2(1, 2);
			va[3] = new Vector2(1, 0);
			Bezier<Vector2> bezier = new Bezier<Vector2>(va);
			System.out.println(bezier.approxLength(4));
			Vector2 out = new Vector2(0, 0);
			int count = 21;
			for (i = 0; i < count; ++i){
				System.out.println("derivate "+bezier.derivativeAt(out, (float)(1.0f / (count - 1) * i)));
				System.out.println("point "+bezier.valueAt(out, (float)(1.0f / (count - 1) * i)));
			}
		}
		
		{
			Vector2[] va = new Vector2[3];
			va[0] = new Vector2(0, 0);
			va[1] = new Vector2(0.5f, 1);
			va[2] = new Vector2(1, 0);
			Bezier<Vector2> bezier = new Bezier<Vector2>(va);
			System.out.println(bezier.approxLength(4));
			Vector2 out = new Vector2(0, 0);
			int count = 21;
			for (i = 0; i < count; ++i){
				System.out.println("derivate "+bezier.derivativeAt(out, (float)(1.0f / (count - 1) * i)));
				System.out.println(bezier.valueAt(out, (float)(1.0f / (count - 1) * i)));
			}
		}
		*/
		/*
		{
			BezierMove bb = new BezierMove(new Vector2(0, 0), new Vector2(0, -5), 30, 5.0f);
			Vector2 out = new Vector2();
			Vector2 der = new Vector2();
			bb.getFirst(out, der);
			System.out.println("der " + der);
			System.out.println("out " + out);
			while (true) {
				if (bb.move(0.05f, out, der)) {
					System.out.println("der " + der);
					System.out.println("out " + out);
					break;
				}
				System.out.println("der " + der);
				System.out.println("out " + out);
			}
		}
		*/
		{
			BezierMove3 bb = new BezierMove3(new Vector3(35, 0, 35), new Vector3(38, 0, 38), 5.0f, 5.0f);
			Vector3 out = new Vector3();
			Vector3 der = new Vector3();
			StringBuilder posString = new StringBuilder();
			StringBuilder derString = new StringBuilder();
			bb.getFirst(out, der);
			System.out.println("der " + der);
			System.out.println("out " + out);
			derString.append("new Vector3"+der+",");
			posString.append("new Vector3"+out+",");
			while (true) {
				if (bb.move(0.05f, out, der)) {
					System.out.println("der " + der);
					System.out.println("out " + out);
					derString.append("new Vector3"+der+",");
					posString.append("new Vector3"+out+",");
					break;
				}
				System.out.println("der " + der);
				System.out.println("out " + out);
				derString.append("new Vector3"+der+",");
				posString.append("new Vector3"+out+",");
			}
			System.out.println(derString);
			System.out.println(posString);
		}
		
		Vector3 x = new Vector3(1, 0, 0);
		Vector3 y = new Vector3(0, 1, 0);
		System.out.println("cross " + x.crs(y));
		
		{
			float fff = 1000 / 5000f;
			System.out.println("fff " + fff);
			fff= 1000 / 5000 * 0.1f;
			System.out.println("fff " + fff);
		}
		
		System.out.println(""+System.nanoTime());
		// 按照定义的数据结构，创建一个Person
//	    PersonMsg.Person.Builder personBuilder = PersonMsg.Person.newBuilder();
//	    personBuilder.setId(1);
//	    personBuilder.setName("叉叉哥aadsfdsafas");
//	    personBuilder.setEmail("xxg@163.com");
//	    personBuilder.addFriends("Friend A");
//	    personBuilder.addFriends("Friend B");
//	    PersonMsg.Person xxg = personBuilder.build();
	    
	    /*TestMsg.Test.Builder tb = TestMsg.Test.newBuilder();
	    tb.setLabel("Hello world");
	    tb.setType(1111);
	    tb.getRepsList().add(111l);
	    tb.getRepsList().add(21l);
	    tb.getRepsList().add(88l);
	    tb.getRepsList().add(5l);
	    //tb.setReps(0, 1000);
	    System.out.println(tb.build().getSerializedSize());*/
	    
	    // 将数据写到输出流，如网络输出流，这里就用ByteArrayOutputStream来代替
	    //序列化后写入包体
//        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
//        com.google.protobuf.CodedOutputStream cos = com.google.protobuf.CodedOutputStream.newInstance(baos); 
//      
//       // tb.writeTo(cos);
//
//        cos.flush();
//        buffer.put(baos.toByteArray());
//	    
//	    // -------------- 分割线：上面是发送方，将数据序列化后发送 ---------------
//	    byte[] byteArray = output.toByteArray();
//	    // -------------- 分割线：下面是接收方，将数据接收后反序列化 ---------------
//	    
//	    // 接收到流并读取，如网络输入流，这里用ByteArrayInputStream来代替
//	    ByteArrayInputStream input = new ByteArrayInputStream(byteArray);
//	    
//	    // 反序列化
//	    PersonMsg.Person xxg2 = PersonMsg.Person.parseFrom(input);
//	    System.out.println("ID:" + xxg2.getId());
//	    System.out.println("name:" + xxg2.getName());
//	    System.out.println("email:" + xxg2.getEmail());
//	    System.out.println("friend:");
//	    List<String> friends = xxg2.getFriendsList();
//	    for(String friend : friends) {
//	      System.out.println(friend);
//	    }
		
//		Thread t = new Thread(new Runnable() {
//			
//			@Override
//			public void run() {
//				// TODO Auto-generated method stub
//				System.out.println("dsfasfvxcvnhg");
//			}
//		});
//		t.start();
//		t.join();
//		
//		Thread t2 = new Thread(() -> {
//			System.out.println("closure");
//		});
//		
//		t2.start();
//		t2.join();
//	    
//		Constructor con = Class.forName("business.skill.ability.ShootAbility").getConstructor(String.class,HashMap.class);
//		HashMap<String, Object> param = new HashMap<String, Object>();
//		param.put("cooldown", 1.0f);
//		param.put("spellTime", 0.5f);
//		param.put("abilityType", AbilityType.NormalAttack);
//		param.put("missileSpeed", 5.0f);
//		param.put("moveMode", BulletMoveMode.Line);
//		param.put("collisionMode", BulletCollisionMode.Any);
//		con.newInstance("gunboy",param);
		
//		while(true){
//			Thread.sleep(20);
//			System.out.println(System.currentTimeMillis());
//		}
		
		long l = 1l;
		l = l << 32;
		System.out.println(l);
		
		{
			pojop p = new pojop();
			p.setA(1);p.setB(2);p.setC(3);p.setD(4);p.setHello("hello");//p.setF(5.0f);
			derive d = new derive();
			Utils.copySuperFieldsFromBean(d, p);
			//Utils.copySuperFieldsToBean(p, d);
			Utils.dumpSuperObject(d);
		}
		{
			derive d = new derive();
			d.setA(1);d.setB(2);d.setC(3);d.setD(4);d.setHello("hello");d.setF(5.0f);
			pojop p = new pojop();
			Utils.copySuperFieldsToBean(d, p);
			Utils.dumpSuperObject(p);
		}
		{
			List<Integer> ll = new LinkedList<Integer>();
			ll.add(1);
			ll.add(2);
			ll.add(3);
			ll.subList(1, 1);
			for (Integer integer : ll.subList(0, 3)) {
				System.out.println(integer);
			}
			for (Integer integer : ll) {
				System.out.println(integer);
			}
		}
		
		{
			DbBagItem.Builder builder = DbBagItem.newBuilder();
			builder.setCharId(5);
			builder.setItemId(2);
			builder.setNumber(3);
			DbBagItem dbBagItem = builder.build();
			Utils.dumpObject(dbBagItem);
			DBagItemBean bagItemBean = new DBagItemBean();
			//Utils.copySuperFieldsToBean(dbBagItem, bagItemBean);
			Utils.copySuperFieldsFromBean(bagItemBean, dbBagItem);
			Utils.dumpObject(bagItemBean);
			DbBagItem.Builder newBuilder = DbBagItem.newBuilder();
			Utils.copySuperFieldsToBean(bagItemBean, newBuilder);
			DbBagItem dbBagItem2 = newBuilder.build();
			Utils.dumpObject(dbBagItem2);
			DBagItemBean bagItemBean2 = new DBagItemBean();
			Utils.copySuperFieldsFromBean(bagItemBean2, dbBagItem2);
			Utils.dumpObject(bagItemBean2);
			
		}
		
		
		{
			UnitWeapon weapon = new UnitWeapon();
			UnitNature nature = new UnitNature();
			weapon.setArmor(5);
			weapon.setAttack(9);
			weapon.setMaxHp(1);
			weapon.setAttackRange(2.3f);
			weapon.setAimTime(3);
			Utils.dumpObject(nature);
			//Utils.addFieldsFromBean(nature, weapon);
			UnitEquipmentBase equipmentBase = weapon;
			//Utils.operationSuperFieldsToBean(equipmentBase, nature, FieldOperation.FO_ADD);
			Utils.operationSuperFieldsFromBean(nature, weapon, FieldOperation.FO_ADD);
			Utils.dumpObject(nature);
			//Utils.operationSuperFieldsToBean(equipmentBase, nature, FieldOperation.FO_SUB);
			Utils.operationSuperFieldsFromBean(nature, weapon, FieldOperation.FO_SUB);
		
//			Class cl = UnitWeapon.class;
//			System.out.println(cl.getDeclaredFields().length);
//			System.out.println(cl.getFields().length);
			
			Utils.dumpObject(nature);
		}
		
	}
	

}
